package com.road.yishi.execaction;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Description :
 * @FileName: CmdExecutor.java
 * @Author :WeiHui.Zhang
 * @Data : 2016年2月1日 下午5:35:39
 * @Version:V1.00
 */
public class CmdExecutor {

	private final static Logger LOG = LoggerFactory.getLogger(CmdExecutor.class);

	private CmdTaskQueue defaultQueue;
	private ThreadPoolExecutor pool;

	/**
	 * 
	 * @param corePoolSize
	 * @param maximumPoolSize
	 * @param keepAliveTime
	 * @param unit
	 * @param prefix
	 * @param needHandler
	 */
	public CmdExecutor(int corePoolSize, int maximumPoolSize, int keepAliveTime, TimeUnit unit, String prefix, RejectedExecutionHandler handler) {
		LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>();
		if (prefix == null) {
			prefix = "";
		}
		ThreadFactory threadFactory = new CustomThreadFactory(prefix);
		if (handler == null) {
			handler = new ThreadPoolExecutor.DiscardPolicy();
		}
		pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
	}

	/**
	 * 执行action队列的线程池
	 * 
	 * @param corePoolSize
	 *            最小线程数，包括空闲线程
	 * @param maxPoolSize
	 *            最大线程数
	 * @param keepAliveTime
	 *            当线程数大于核心时，终止多余的空闲线程等待新任务的最长时间
	 * @param cacheSize
	 *            执行队列大小
	 * @param prefix
	 *            线程池前缀名称
	 */
	public CmdExecutor(int corePoolSize, int maxPoolSize, int keepAliveTime, String prefix) {
		TimeUnit unit = TimeUnit.MINUTES;
		LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>();
		RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
		if (prefix == null) {
			prefix = "";
		}
		ThreadFactory threadFactory = new CustomThreadFactory(prefix);
		pool = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
		defaultQueue = new AbstractCmdTaskQueue(this);
	}

	public CmdTaskQueue getDefaultQueue() {
		return defaultQueue;
	}

	public void enDefaultQueue(CmdTask cmdTask) {
		defaultQueue.enqueue(cmdTask);
	}

	public void stop() {
		if (!pool.isShutdown()) {
			pool.shutdown();
		}
	}

	public void execute(CmdTask cmdTask) {
		pool.execute(cmdTask);
	}

	/**
	 * 对没有执行的命令强制执行
	 * 
	 * @author jackson.zhang
	 *
	 */
	class CustomRejectedExecutionHandler implements RejectedExecutionHandler {

		@Override
		public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
			LOG.info("Current taskNum : " + executor.getTaskCount() + " , current activeCount : " + executor.getActiveCount());
			// new Thread(r).start();
			executor.execute(r);
		}

	}
}
